config_path = "./config.cfg"

import logging
from logging import debug
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)

import numpy as np


import re


def _find_deli(lines):
    """Estimate the delimiter of csv file by comparing a number
    of lines from the csv file"""
    possi_deli = [';', ',']
    longest_num_of_el = 0
    num_of_el = 0
    deli_to_use = possi_deli[0]
    for deli in possi_deli:
        for i, line in enumerate(lines):
            if i == 0:
                num_of_el = len(line.split(deli))
            elif num_of_el == len(line.split(deli)):
                pass
            else:
                num_of_el = 0
        if longest_num_of_el < num_of_el:
            longest_num_of_el = num_of_el
            deli_to_use = deli

    if 1 > longest_num_of_el:
        logging.warning("Could not find delimiter")

    return deli_to_use

def _find_turb_name(names):
    """ Simple detection of the turbine name.
    There is no check on the occurrence so could be improved.
    Extracting of the variable names are also performed"""
    hest = [name.split('-') for name in names]
    clean_names = []
    turb = "unknown"
    for name in hest:
        if 2 == len(name):
            turb = name[0]
            clean_names.append(name[1].lower())
        elif 3 == len(name):
            clean_names.append((name[1]+name[2]).lower())
        else:
            clean_names.append(name[0].lower())
    return turb, clean_names

def _add_missing_names(names):
    """ Handle the case where compressed data are used in the CSV file.
    If exactly half is missing it is assumed to be time stamps if not do nothing"""
    num_of_missing = 0
    old_len = len(names)
    for name in names:
        if name == "":
            num_of_missing += 1
    if num_of_missing * 2 == len(names):
        c = np.arange(0, len(names), 2)
        for pos in c:
            time_label = names[pos] + "time"
            names.insert(pos, time_label)
        names = names[0:old_len]
    return names

def _estimate_para_type(names):
    """ Estimate type of parameter assume it to be float unless it match one of the strings."""
    para_types = ["Float64Col(pos=" + str(i) + ")" for i in range(len(names))]
    for i, name in enumerate(names):
        match = re.search(r"^(.*time.*)*(.*txt.*|.*alarm.*|.*turbid.*)*", name.lower())
        if match.group(1):
            para_types[i] = "Time64Col(pos=" + str(i) + ")"
        elif match.group(2):
            para_types[i] = "StringCol(itemsize=10, shape=(), dflt='', pos=" + str(i) + ")"
        else:
            pass
    return para_types

def estimate_para_type_from_data(data):
    names = data.dtype.names
    para_types = _estimate_para_type(names)
    return names, para_types

def read_head(file_name):
    """
    #>>> save_describ(cl_names, para_types)
    #>>> turb, names, para_types, deli = read_head("../../test_data/UTHA01.csv")
    #>>> turb, names, para_types, deli = read_head("../../test_data/WH1114-2011.csv")
    >>> turb, names, para_types, deli = read_head("../../data/25Hz/2012-08-31-00_25Hz.csv")
    """
    fil_str = file_name
    head_len = 5
    # Read header lines
    f = open(fil_str, 'r')
    lines = [f.readline().replace('\n', '').replace('\r', '') for i in range(head_len)]
    deli = _find_deli(lines)
    header = lines[0]

    # Cleaning the header names from string identifiers.
    names = header.replace('"', '').replace("'", '').replace(' ', '').replace('[', '').replace(']', '').split(deli)

    turb, cl_names = _find_turb_name(names)
    names = _add_missing_names(cl_names)
    para_types = _estimate_para_type(names)
    debug("Parameters:")
    debug(names)

    #debug(turb)
    #debug(deli)
    f.close()
    return turb, names, para_types, deli

def save_describ(names, para_types):
    """
    Create the description file
    """
    db_class_file = "particle.py"
    f = open(db_class_file, 'w')
    f.write("import tables as tb\n")
    f.write("class Particle(tb.IsDescription):\n")
    for i, name in enumerate(names):
        f.write(("    " + name + " = tb." + para_types[i] + "\n"))
    return


if __name__=='__main__':
    import header_reading
    import doctest
    doctest.testmod(header_reading, verbose=False)

